From b456db8cf4c8c7d52d4a5c90948bd659b0716de6 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 14 Dec 2015 16:34:00 +0100 Subject: [PATCH] wayland: Check transient loop Gdk Wayland backend walks up the transient windows tree, but does not check for cycles when doing so. As a result, if two or more windows are transient to each other, the Wayland gdk backend will enter an infinite loop. While this is clearly a bug in the application, gtk+/gdk should be more robust and handle such errors more gracefully. To avoid looping infinitely at various point in the code, check for a possible loop when setting the transient relationship and deny the request to set a window transient for another if that would create a loop. Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759299 --- gdk/wayland/gdkwindow-wayland.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 753aac58ec..0776471892 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -1943,12 +1943,33 @@ gdk_wayland_window_set_startup_id (GdkWindow *window, { } +static gboolean +check_transient_for_loop (GdkWindow *window, + GdkWindow *parent) +{ + while (parent) + { + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl); + + if (impl->transient_for == window) + return TRUE; + parent = impl->transient_for; + } + return FALSE; +} + static void gdk_wayland_window_set_transient_for (GdkWindow *window, GdkWindow *parent) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (check_transient_for_loop (window, parent)) + { + g_warning ("Setting %p transient for %p would create a loop", window, parent); + return; + } + if (impl->subsurface) unmap_subsurface (window); -- 2.30.2